import '../styles/middle.scss'
import 'react-grid-layout/css/styles.css'
import 'react-resizable/css/styles.css'
// import _ from "lodash";
import React, { useState, useEffect } from 'react';
import { useDrop, DropTargetMonitor } from 'react-dnd';
// import Draggable, { DraggableCore } from 'react-draggable'
import GridLayout, { Responsive, WidthProvider } from "react-grid-layout"; //自由拖拽排列
import DynamicEngine from './dynamicEngine'
import UUID from 'uuid-js'
import { connect } from 'react-redux';
import * as Actions from '../../redux/Actions'
import { memo, useMemo } from 'react'
// import ScorpioMenu from 'scorpio-menu';
// import { Menu, Item, Separator, Submenu, useContextMenu } from 'react-contexify';
// import 'react-contexify/dist/ReactContexify.css';

const TargetBox = memo((props: any) => {
  // const [items, setItems] = useState<itemsProps>([]);
  const items = props.itemsInEditing
  // 第一个参数是 collect 方法返回的对象，第二个参数是一个 ref 值，赋值给 drop 元素
  const [{ isOver }, droper] = useDrop({
    // accept 是一个标识，需要和对应的 drag 元素中 item 的 type 值一致，否则不能感应
    accept: 'box',
    // collect 函数，返回的对象会成为 useDrop 的第一个参数，可以在组件中直接进行使用
    collect: (minoter: DropTargetMonitor) => ({
      isOver: minoter.isOver()
    }),
    drop: (item: { h: number; type: string; x: number, id: string, classify: string }, monitor) => {
      let parentDiv = document.getElementById('middleEditor'),
        pointRect = parentDiv!.getBoundingClientRect(),
        top = pointRect.top,
        pointEnd = monitor.getSourceClientOffset(),
        y = pointEnd!.y < top ? 0 : pointEnd!.y - top,
        col = 24, // 网格列数
        cellHeight = 2.8,
        w = item.type === 'Icon' ? 3 : col;

      // 转换成网格规则的坐标和大小
      let gridY = Math.ceil(y / cellHeight);

      const itemBox = {
        x: 0,
        y: gridY,
        w: w,
        h: item.h,
        i: 'box',
        id: item.id,
        uid: UUID.create(4).toString(),
        type: item.type,
        classify: item.classify,
        isBounded: true,
        config: require(`../boxs/${item.classify}/${item.id}/${item.id}.ts`).default.config
      }

      props.saveItemsVal(itemBox)

      props.insertItemsVal([...items, itemBox])

      // setItems([...items, itemBox])
    }
  })
  const opacity = isOver ? 0.7 : 1;

  const [currentItemUid, setcurrentItemUid] = useState(-1)

  const onDragStart = useMemo(() => {
    return (data: any, index: any) => {
      const item = items[index.i]
      props.saveItemsVal(item)
      setcurrentItemUid(item.uid)
    }
  }, [items])

  const ResizeStop = useMemo(() => {
    return (layout: any, oldItem: any, newItem: any, placeholder: any, e: any, element: any) => {
      props.modifyItemsVal(newItem)
      console.log(layout, newItem)
    }
  }, [items])

  const dragStop = useMemo(() => {
    return (layout: any, oldItem: any, newItem: any, placeholder: any, e: any, element: any) => {
      props.modifyItemsVal(newItem)
      console.log(layout, newItem)
    }
  }, [items])

  // 删除组件
  const keydownFn = (e: KeyboardEvent) => {
    if (e!.keyCode === 8 || e!.keyCode === 46) {
      if (currentItemUid !== -1) {
        let newItems = JSON.parse(JSON.stringify(items))
        newItems = newItems.filter((i: { uid: number }) => i.uid !== currentItemUid)
        // setItems(newItems)
      }
    }
  }

  useEffect(() => {
    document.addEventListener('keydown', keydownFn, false)
    return () => {
      document.removeEventListener('keydown', keydownFn, false)
    }
  }, [currentItemUid])

  return (
    <div>
      <div id="middleEditor" className="box" ref={droper} style={{ opacity }}>
        <GridLayout
          margin={[1, 1]}
          rowHeight={2}
          isBounded={true}
          onDragStart={onDragStart}
          onResizeStop={ResizeStop}
          onDragStop={dragStop}
          width={375}>
          {items.map((i: any, index: number) => (
            <div className="item-wrap" key={index} data-grid={i}>
              <DynamicEngine {...i} />
            </div>
          ))}
          {/* <Draggable
            bounds="parent">
            <div className="box" style={{ width: '200px', height: '200px', background: 'yellow' }}></div>
          </Draggable> */}
          {/* <Draggable
          bounds="parent">
          <div className="box" style={{ width: '200px', height: '200px', background: 'yellow' }}></div>
        </Draggable> */}
        </GridLayout>
      </div>
    </div >
  )
})

function mapStateToProps(state: any, ownProps: any) {
  return {
    currentBoxVal: state.currentBoxVal,
    itemsInEditing: state.itemsInEditing
  }
}

function mapDispatchToProps(dispatch: any, ownProps: any) {
  return {
    insertItemsVal: (data: any) => {
      dispatch(Actions.insertItemsVal(data))
    },
    saveItemsVal: (data: any) => {
      dispatch(Actions.saveItemsVal(data))
    },
    modifyItemsVal: (data: any) => {
      dispatch(Actions.modifyItemsVal(data))
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(TargetBox)